package cn.xxm.strategy.pay.processor;

import cn.xxm.strategy.pay.annotation.PayType;
import cn.xxm.strategy.pay.context.SourceHandlerContext;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Component
@Slf4j
public class SourceHandlerProcessor implements BeanFactoryPostProcessor {

	private static final String HANDLER_PACKAGE = "cn.xxm.strategy.pay.handler";

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		Map<String, Class<?>> handlerMap = new HashMap<>();
		try {
			ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader();
			ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(
					(BeanDefinitionRegistry) beanFactory, true);
			Set<BeanDefinition> bds = scanner.findCandidateComponents(HANDLER_PACKAGE);
			for (BeanDefinition beanDefinition : bds) {
				Class<?> clazz = originClassLoader.loadClass(beanDefinition.getBeanClassName());
				Annotation[] annotations = clazz.getAnnotationsByType(PayType.class);
				if (annotations != null && annotations.length > 0) {
					handlerMap.put(((PayType) annotations[0]).value(), clazz);
				}
			}
		} catch (Exception e) {
		    log.error("",e);
		    throw new RuntimeException("加载handler bean信息失败");
		}
		log.info("初始化handlerContext:{}",JSONObject.toJSONString(handlerMap));
		SourceHandlerContext handlerContext =new SourceHandlerContext(handlerMap);
		beanFactory.registerSingleton(SourceHandlerContext.class.getName(), handlerContext);
		

	}

}
